/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */
package servermonitor;

import java.io.IOException;
import java.net.ServerSocket;
import java.net.Socket;
import java.util.concurrent.Semaphore;
import java.util.logging.Level;
import java.util.logging.Logger;

/**
 *
 * @author otaviokz
 */
public class Monitor {

    private static int numPhilosophers = 5; //If bigger than 26, some philosophers will get weird names :-P
    private static String philosophers[] = {"Protogoras", "Gorgias", "Prodicus", "Hippias", "Lycophron", "Solon", "Thales",
        "Plato", "Socrates", "Pythagoras", "Heraclitus", "Parmenides", "Democritus", "Antisthenes", "Fredo", "Diogenes", "Aristotle",
        "Pirrho", "Epicurus", "Zeno", "Chrysippus", "Posidonius", "Apollonius", "Plutarco", "Epictetus", "Plotinus"};
    private static Semaphore semList[];
    private static Semaphore chairs;
    private static ServerSocket server;
    private static String philosoferJarPath = "Philosofer.jar";

    /**
     * @param args the command line arguments
     */
    public static void main(String[] args) {
        if (args.length == 1)
        {

            //philosoferJarPath = args[0];
            numPhilosophers = Integer.parseInt(args[0]);
            semList = new Semaphore[numPhilosophers];
            System.out.println(String.valueOf(numPhilosophers));
            setSemaphores();
            raisePhilosophers();
            handleConnections();
        }
        else
        {
            printUsage();
        }
    }

    //self explaining
    private static void setSemaphores() {
        for (int i = 0; i < numPhilosophers; i++) {
            semList[i] = new Semaphore(1, true);
        }

        chairs = new Semaphore(numPhilosophers - 1, true);
    }

    //lauch the philosopher threads
    private static void raisePhilosophers() {
        try {
            for (int i = 0; i < numPhilosophers; i++) {
                System.out.printf("Calling philosopher %d\n", i);
                System.out.flush();
                //Process pr = new Process();

                Runtime.getRuntime().exec(new String[]{"sudo", "java", "-jar", "Philosofer.jar"});
                //Runtime.getRuntime().exec(new String[]{"java", " -jar", philosoferJarPath});

            }
        } catch (IOException ex) {
            Logger.getLogger(Monitor.class.getName()).log(Level.SEVERE, null, ex);
        } catch (Exception e) {
            Logger.getLogger(Monitor.class.getName()).log(Level.SEVERE, null, e);
        }
    }

    private static void handleConnections() {
        try {
            //instatiates the socket server
            server = new ServerSocket(10000, numPhilosophers);
            Semaphore left, right;

            for (int i = 0; i
                    < numPhilosophers; i++) {
                //wait for philosopher connections
                Socket connection = server.accept();
                if (i == 0) {
                    left = semList[semList.length - 1];
                    right = semList[0];
                } else {
                    left = semList[i];
                    right = semList[(i + 1) % numPhilosophers];
                }

                String name;

                if (i < philosophers.length) {
                    name = philosophers[i];
                } else {
                    name = "Philosopher " + String.valueOf(i) + "'us";
                }

                //Launches a different thread for each philosopher thread
                ServerThread st = new ServerThread(connection, name, left, right, chairs);
                Thread t = new Thread(st);
                t.start();

                System.out.println(philosophers[i] + " started!");
            }
        } catch (Exception ex) {
            System.out.println("ERROR: " + ex.getMessage());
        }
    }

    private static void printUsage() {
        System.out.println("usage: java -jar ServerMonitor.jar <path to philosopher jar>");
    }
}
